package com.want.client;

import lombok.Data;
import org.springframework.http.HttpHeaders;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.reactive.function.client.ClientRequest;
import org.springframework.web.reactive.function.client.WebClient;

import java.util.Map;
import java.util.Optional;

/**
 * @author WangZhiJian
 * @since 2021/12/4 0004
 */
public interface Client {

    WebClient.ResponseSpec exec(ClientRequest request);

    @Data
    public static class DefaultClient implements Client {

        private WebClient webClient;

        public DefaultClient(WebClient webClient) {
            this.webClient = webClient;
        }

        public DefaultClient() {
            ReactorClientHttpConnector reactorClientHttpConnector = new ReactorClientHttpConnector();
            webClient = WebClient.builder()
                    .clientConnector(reactorClientHttpConnector)
                    .build();
        }

        @Override
        public WebClient.ResponseSpec exec(ClientRequest req) {
            return webClient.
                    method(req.method())
                    .uri(req.url())
                    .headers(httpHeaders ->
                            Optional.ofNullable(req.headers())
                                    .map(HttpHeaders::entrySet)
                                    .ifPresent(entries -> entries.forEach(entry -> httpHeaders.addAll(entry.getKey(),entry.getValue()))))
                    .attributes(attMap ->
                            Optional.ofNullable(req.attributes())
                                    .map(Map::entrySet)
                                    .ifPresent(entries -> entries.forEach(entry -> attMap.put(entry.getKey(),entry.getValue()))))
                    .body(req.body())
                    .cookies(cookies ->
                            Optional.ofNullable(req.cookies())
                                    .map(Map::entrySet)
                                    .ifPresent(entries -> entries.forEach(entry -> cookies.addAll(entry.getKey(),entry.getValue()))))
                    .retrieve();
        }
    }
}
